package cn.ronghuanet.org.service.impl;

import cn.ronghuanet.base.constants.BaseConstants;
import cn.ronghuanet.base.exception.BusinessException;
import cn.ronghuanet.base.exception.ResponseCode;
import cn.ronghuanet.base.exception.RonghuaAssert;
import cn.ronghuanet.base.util.MD5Utils;
import cn.ronghuanet.org.domain.Employee;
import cn.ronghuanet.org.domain.Shop;
import cn.ronghuanet.org.domain.ShopEmployee;
import cn.ronghuanet.org.domain.ShopOperateLog;
import cn.ronghuanet.org.dto.ShopAdminDTO;
import cn.ronghuanet.org.dto.ShopRegisterDTO;
import cn.ronghuanet.org.mapper.EmployeeMapper;
import cn.ronghuanet.org.mapper.ShopEmployeeMapper;
import cn.ronghuanet.org.mapper.ShopMapper;
import cn.ronghuanet.org.mapper.ShopOperateLogMapper;
import cn.ronghuanet.org.service.IShopService;
import cn.ronghuanet.base.service.impl.IBaseServiceImpl;
import cn.ronghuanet.user.domain.Logininfo;
import cn.ronghuanet.user.mapper.LogininfoMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lijie
 * @since 2023-08-15
 */
@Service
public class ShopServiceImpl extends IBaseServiceImpl<Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private ShopEmployeeMapper shopEmployeeMapper;

    @Autowired
    private ShopOperateLogMapper logMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Transactional
    @Override
    public void settlement(ShopRegisterDTO dto) {

        ShopAdminDTO admin = dto.getAdmin();
        // 1 参数校验
        validate(dto, admin);

        Shop shop = new Shop();
        ShopOperateLog log = new ShopOperateLog();
        // 4 对店铺信息(名称,地址,logo)做审核  文本审核+图片审核
        /*List<String> text = Arrays.asList(dto.getName(),dto.getAddress());
        List<String> img = Arrays.asList(dto.getLogo());*/
        //Map<String,Object> map = BaiduAuditUtil.censor(text,img);
        Map<String,Object> map = new HashMap<>();
        map.put("success",true);
        Boolean censorResult = (Boolean) map.get("success");
        if(censorResult){
            shop.setState(BaseConstants.Shop.STATE_WAIT_ACTIVE);
            log.setOperateType(2);
            log.setNote("审核通过!");
        }else{
            shop.setState(BaseConstants.Shop.STATE_REJECT_AUDIT);
            log.setOperateType(3);
            log.setNote(map.get("message").toString());
        }

        // 2 保存店铺信息到数据库表
        BeanUtils.copyProperties(dto,shop);
        shop.setRegisterTime(new Date());
        shopMapper.insert(shop);

        // 3 保存店铺管理员信息到数据库
        // 思考? 如果这个店铺管理员已经存在怎么办??
        // 方案一: 直接返回错误信息给前端,不让新增, 提示"该管理员已存在,请直接新增店铺!"
        // 方案二: 新增的店铺就用已经存在的管理员作为店铺的管理员 新增店铺和已存在的管理员进行绑定  采纳这种
        // 3.1 先判断管理员是否存在  根据手机号判断是否是同一个人
        Employee employee = employeeMapper.loadByPhone(admin.getPhone());

        if(Objects.isNull(employee)){
            // 3.1.1 如果不存在,新增管理员信息,并将新增的管理员id和店铺id做绑定
            // 3.1.1.1 判断用户的用户名和邮箱是否重复
            employee = employeeMapper.loadByUsernameOrEmail(admin.getUsername(),admin.getEmail());
            if(Objects.nonNull(employee)){
                throw new BusinessException("管理员的用户名或邮箱已存在,请重新输入!");
            }
            // 新增logininfo
            Logininfo logininfo = new Logininfo();
            logininfo.setUsername(admin.getUsername());
            logininfo.setPhone(admin.getPhone());
            logininfo.setEmail(admin.getEmail());
            // 密码要做加盐加密处理
            String salt = UUID.randomUUID().toString();
            String password = MD5Utils.encrypByMd5("ronghuanet"+salt+admin.getPassword()+"123456");
            logininfo.setSalt(salt);
            logininfo.setPassword(password);
            logininfo.setType(0);
            logininfo.setDisable(0);
            logininfoMapper.insert(logininfo);

            // 3.1.1.2 新增管理员
            employee = new Employee();
            BeanUtils.copyProperties(logininfo,employee);
            employee.setId(null);
            employee.setLogininfoId(logininfo.getId());
            // 管理员要等店铺审核通过激活以后,才能正常登录使用
            employee.setState(BaseConstants.Employee.STATE_WAIT_AUTID);
            employeeMapper.insert(employee);
        }
        // 3.1.1.3 将新增的管理员和店铺做绑定
        ShopEmployee shopEmployee = new ShopEmployee();
        shopEmployee.setShopId(shop.getId());
        shopEmployee.setEmployeeId(employee.getId());
        shopEmployee.setIsAdmin(1);
        shopEmployeeMapper.insert(shopEmployee);

        // 保存操作日志
        log.setShopId(shop.getId());
        log.setOperateTime(new Date());
        log.setOperateId(0L);       // 自动
        logMapper.insert(log);

        // 4.1 审核成功,修改店铺状态=待激活,发送激活邮件给店铺管理员,进行激活
        if(censorResult){
            // 4.1.3 发送激活邮件给店铺管理员  @TODO
        }else{
            // 4.2.3 发送失败通知邮件给店铺管理员 @TODO
        }
    }

    /**
     * 将代码块抽取为一个方法  快捷键  ctrl+alt+m
     * @param dto
     * @param admin
     */
    private void validate(ShopRegisterDTO dto, ShopAdminDTO admin) {
        // 1.1 非空校验  这段非空校验放在参数类中使用jsr303注解进行校验
        /*if(dto == null || admin == null || StringUtils.isBlank(dto.getName()) || StringUtils.isBlank(dto.getTel())
                || StringUtils.isBlank(dto.getAddress()) || StringUtils.isBlank(admin.getUsername())
                || StringUtils.isBlank(admin.getPhone())  || StringUtils.isBlank(admin.getEmail())
                || StringUtils.isBlank(admin.getPassword())  || StringUtils.isBlank(admin.getConfirmPassword())){
            throw new BusinessException("参数异常,请检查后重新提交!");
        }*/
        // 上面这个非空校验,可以用断言,但是不建议, 一般如果参数校验过多的话,不建议用断言,因为也比较麻烦

        // 1.2 判断两次密码是否一致
        /*if(!admin.getPassword().equals(admin.getConfirmPassword())){
            throw new BusinessException("密码不一致,请检查后重新输入!");
        }*/
        RonghuaAssert.isEq(admin.getPassword(),admin.getConfirmPassword(), ResponseCode.RESPONSE_CODE_40011);

        // 1.3 校验店铺名称是否重复
        // 1.3.1 根据店铺名称查询店铺表
        Shop shop = shopMapper.loadByName(dto.getName());

        // 1.3.2 如果存在就是说明名称重复,就要抛出异常
        /*if(Objects.nonNull(shop)){
            throw new BusinessException("该店铺名称已存在,请重新输入!");
        }*/
        RonghuaAssert.isNull(shop,ResponseCode.RESPONSE_CODE_40012);
    }
}
